﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIA.Foundation;
using VIA.Integration.Domain;
using VIA.Integration.Presentation;
using VIA.Integration;
using VIA.Integration.Presentation.ViewModel;
using VIA.Presentation;
using System.Collections.ObjectModel;
using VIA.SiMoJi.Domain.Inspection;
using VIA.SiMoJi.Domain.Electronics;
using VIA.RbacPassport;
using VIA.Presentation.Services;

namespace VIA.SiMoJi.Presentation.ViewModel.Inspection
{
    [ViewModel(typeof(IEquipmentView), IsShared = true)]
    public class EquipmentViewModel1 : ViewModel<IEquipmentView>
    {
        protected readonly ILogger _logger;

        protected readonly IMessageService _messageService;

        protected readonly IServiceProvider _service;

        protected readonly IOptionRepository _optionRepository;

        protected readonly IDispatcherService _dispatcherService;

        protected readonly Inspector _inspector;

        protected readonly IShellService _shellService;

        private AutomaticModel _selectedAutomatic;

        private Part _selectedPart;

        private ObservableCollection<IPart> _part;
        private bool _isEditEnable = true;

        public ObservableCollection<AutomaticModel> Automatics { get; } = new ObservableCollection<AutomaticModel>();

        public ObservableCollection<IPart> Parts
        {
            get
            {
                return _part;
            }
            set
            {
                SetProperty(ref _part, value, "Parts");
            }
        }

        public AutomaticModel SelectedAutomatic
        {
            get
            {
                return _selectedAutomatic;
            }
            set
            {
                SetProperty(ref _selectedAutomatic, value, "SelectedAutomatic");
            }
        }

        public Part SelectedPart
        {
            get
            {
                return _selectedPart;
            }
            set
            {
                if (SetProperty(ref _selectedPart, value, "SelectedPart"))
                {
                    LoadAutomatics(_selectedPart);
                }
            }
        }

        public IRelayCommand EditPartCommand { get; }

        public IRelayCommand EditAutomaticCommand { get; }

        public IRelayCommand AddStationCommand { get; }

        public IRelayCommand RemoveStationCommand { get; }

        readonly ICurrentUser _currentUser;
        public EquipmentViewModel1(IServiceProvider service, ICommandFactory commandFactory, Inspector inspector)
        {
            _service = service;
            _inspector = inspector;
            _inspector.StatusChanged += Inspector_StatusChanged;
            _inspector.ManualAutoStateChanged+=(s,e)=> RaiseCanExecuteChanged();
            _logger = service.GetRequiredService<ILogger<EquipmentViewModel1>>();
            _dispatcherService = service.GetRequiredService<IDispatcherService>();
            _messageService = service.GetRequiredService<IMessageService>();
            _shellService = service.GetRequiredService<IShellService>();
            _currentUser=service.GetRequiredService<ICurrentUser>();
            EditPartCommand = commandFactory.Create((Action<IPart>)EditPart, (part) => IsEditEnable());
            EditAutomaticCommand = commandFactory.Create((Action<AutomaticModel>)EditAutomatic, (AutomaticModel) => IsEditEnable());
            RefreshBOM();
        }

        protected override void OnViewLoaded()
        {
            RaiseCanExecuteChanged();
        }

        public bool IsEditEnable()
        {
            return _isEditEnable && (Electronic.Default.DI04_手动自动旋钮手动.Value || !Electronic.Default.DI05_手动自动旋钮自动.Value);
        }

        private void Inspector_StatusChanged(object? sender, PartStateChangedEventArgs e)
        {
            if (e.CurrentState == RunState.Running)
            {
                _isEditEnable = false;
            }
            else
            {
                _isEditEnable = true;
            }
            RaiseCanExecuteChanged();
        }

        void RaiseCanExecuteChanged()
        {
            _dispatcherService.Invoke(new Action(() =>
            {
                EditPartCommand.RaiseCanExecuteChanged();
                EditAutomaticCommand.RaiseCanExecuteChanged();
            }));
        }
        private void EditPart(IPart part)
        {
            try
            {
                EditorFactory.Default.ShowEditorView(part);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                _messageService.ShowError(_shellService.RootDialogHost, ex.Message);
            }
        }

        private void EditAutomatic(AutomaticModel model)
        {
            try
            {
                EditorFactory.Default.ShowEditorView(model.GetAutomatic());
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                _messageService.ShowError(_shellService.RootDialogHost, ex.Message);
            }
        }

        private void LoadAutomatics(IPart part)
        {
            try
            {
                if (part == null)
                {
                    return;
                }

                Automatics.Clear();
                List<IAutomatic> list = new List<IAutomatic>();
                part.Traverse(delegate (IPart x)
                {
                    x.Automatics.ForEach((IAutomatic y) => list.AddIf(y, (IAutomatic t) => !list.Contains(t)));
                });
                Automatics.AddRange(list.Select((IAutomatic x) => new AutomaticModel(x)));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                _messageService.ShowError(_shellService.RootDialogHost, ex.Message);
            }
        }

        internal void RefreshBOM()
        {
            if (_inspector != null)
            {
                Parts = new ObservableCollection<IPart>(new InspectorEngine[1] { _inspector });
            }
            else
            {
                _logger.LogWarning("当前程序未注册Inspector，未能加载BOM");
            }
        }
    }
}
